/*
    SpawnSurance - Minecraft Plugin for casualty insurance of inventory contents
    Copyright (C) 2012 Ernest Pazera

    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
     */
package com.pdg.mcplugin.spawnsurance;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import java.util.logging.Logger;

import org.bukkit.Material;
import org.bukkit.configuration.file.YamlConfiguration;

public class Configuration {
	//plugin
	private SpawnSurance plugin;
	public SpawnSurance getPlugin(){
		return plugin;
	}
	
	//logger
	public Logger getLogger(){
		return getPlugin().getLogger();
	}
	
	private void loadConfiguration(){
		//ensure that the data folder is present
		getPlugin().getDataProvider().ensureDataFolder();
		
		//point to the configuration file
		File theFile = new File(getPlugin().getDataFolder(),Constants.configurationFile);
		
		//does the file exist?
		if(theFile.exists()){
			//the file exists
			//load the configuration
			YamlConfiguration config = YamlConfiguration.loadConfiguration(theFile);
			
			//does the configuration include an entry for material?
			if(config.contains(Constants.configurationMaterial))
			{
				//it contains an entry for material
				
				//grab the entry
				String theString = config.getString(Constants.configurationMaterial);
				
				//parse to a material
				Material theMaterial = Material.getMaterial(theString);
				
				//is the material valid?
				if(theMaterial!=null){
					//valid material
					material = theMaterial;
				}else{
					//not valid, use default
					material = Constants.materialDefault;
				}
			}else{
				//no entry
				//use default
				material = Constants.materialDefault;
			}
			//check for entry for minimum
			if(config.contains(Constants.configurationMinimum) && config.isInt(Constants.configurationMinimum))
			{
				//valid entry, use it
				minimum = config.getInt(Constants.configurationMinimum);
			}else{
				//no valid entry, use default
				minimum = Constants.minimumDefault;
			}
			//check for an entry for maximum
			if(config.contains(Constants.configurationMaximum) && config.isInt(Constants.configurationMaximum))
			{
				//entry found, use it
				maximum = config.getInt(Constants.configurationMaximum);
			}else{
				//no entry, use default
				maximum = Constants.maximumDefault;
			}
			//check for an entry for acceleration
			if(config.contains(Constants.configurationAcceleration) && config.isInt(Constants.configurationAcceleration))
			{
				//valid entry, use it
				acceleration = config.getInt(Constants.configurationAcceleration);
			}else{
				//no entry, use default
				acceleration = Constants.accelerationDefault;
			}
			//check for message enabled
			if(config.contains(Constants.configurationMessageEnabled) && config.isBoolean(Constants.configurationMessageEnabled))
			{
				//valid entry, use it
				messageEnabled = config.getBoolean(Constants.configurationMessageEnabled);
			}else{
				//no entry, use default
				messageEnabled = Constants.messageEnabledDefault;
			}
			//check for message text
			if(config.contains(Constants.configurationMessageText) && config.isBoolean(Constants.configurationMessageText))
			{
				//valid entry, use it
				messageText = config.getString(Constants.configurationMessageText);
			}else{
				//no entry, use default
				messageText = Constants.messageTextDefault;
			}
			if(config.contains(Constants.configurationPaySource) && config.isString(Constants.configurationPaySource)){
				paySource = PaySource.parsePaySource(config.getString(Constants.configurationPaySource));
				
			}else{
				paySource = Constants.paySourceDefault;
			}
			if(config.contains(Constants.configurationFilterState) && config.isString(Constants.configurationFilterState)){
				filterState = FilterState.valueOf(config.getString(Constants.configurationFilterState));
			}else{
				filterState = Constants.filterDefault;
			}
			filterMaterials.clear();
			if(config.contains(Constants.configurationFilterMaterials)){
				List<String> theMaterialStrings = config.getStringList(Constants.configurationFilterMaterials);
				Iterator<String> iterator = theMaterialStrings.iterator();
				while(iterator.hasNext()){
					String theString = iterator.next();
					Material theMaterial = Material.valueOf(theString);
					filterMaterials.add(theMaterial);
				}
			}
		}else{
			//the file does not exist
			//use defaults for everything
			material = Constants.materialDefault;
			minimum = Constants.minimumDefault;
			maximum = Constants.maximumDefault;
			acceleration = Constants.accelerationDefault;
			messageEnabled = Constants.messageEnabledDefault;
			messageText = Constants.messageTextDefault;
			paySource = Constants.paySourceDefault;
			filterState = Constants.filterDefault;
			filterMaterials.clear();
		}
	}
	
	private void saveConfiguration(){
		//ensure that data folder exists
		getPlugin().getDataProvider().ensureDataFolder();
		
		//point to file location for configuration
		File theFile = new File(getPlugin().getDataFolder(),Constants.configurationFile);
		
		//create a configuration file
		YamlConfiguration config = new YamlConfiguration();
		
		//set entries for all configuration data
		config.set(Constants.configurationMaterial, material.toString());
		config.set(Constants.configurationMinimum, minimum);
		config.set(Constants.configurationMaximum, maximum);
		config.set(Constants.configurationAcceleration, acceleration);
		config.set(Constants.configurationMessageEnabled, messageEnabled);
		config.set(Constants.configurationMessageText,messageText);
		config.set(Constants.configurationPaySource, paySource.getStringValue());
		config.set(Constants.configurationFilterState, filterState.toString());
		
		List<String> theStringList = new ArrayList<String>();
		Iterator<Material> iterator = getFilterMaterials().iterator();
		while(iterator.hasNext()){
			Material theMaterial = iterator.next();
			theStringList.add(theMaterial.toString());
		}
		config.set(Constants.configurationFilterMaterials, theStringList);
		
		
		try {
			//save the configuration file
			config.save(theFile);
		} catch (IOException e) {
			//something didn't work!
			e.printStackTrace();
		}
	}
	
	//constructor
	public Configuration(SpawnSurance thePlugin){
		filterMaterials = new HashSet<Material>();
		plugin = thePlugin;
		//load the configuration
		loadConfiguration();
	}
	
	//material
	private Material material;
	public Material getMaterial(){
		return material;
	}
	public void setMaterial(Material theMaterial){
		material = theMaterial;
		saveConfiguration();
	}
	
	//minimum cost
	private Integer minimum;
	public Integer getMinimum(){
		return minimum;
	}
	public void setMinimum(Integer theMinimum){
		minimum = theMinimum;
		saveConfiguration();
	}
	
	//maximum cost
	private Integer maximum;
	public Integer getMaximum(){
		return maximum;
	}
	public void setMaximum(Integer theMaximum){
		maximum = theMaximum;
		saveConfiguration();
	}
	
	//acceleration
	private Integer acceleration;
	public Integer getAcceleration(){
		return acceleration;
	}
	public void setAcceleration(Integer theAcceleration){
		acceleration = theAcceleration;
		saveConfiguration();
	}

	private Boolean messageEnabled;
	public boolean getMessageEnabled() {
		return messageEnabled;
	}
	public void setMessageEnabled(boolean theMessageEnabled){
		messageEnabled = theMessageEnabled;
		saveConfiguration();
	}
	
	private String messageText;
	public String getMessageText(){
		return messageText;
	}
	public void setMessageText(String theMessageText){
		messageText = theMessageText;
		saveConfiguration();
	}
	
	private PaySource paySource;
	public PaySource getPaySource(){
		return paySource;
	}
	public void setPaySource(PaySource thePaySource){
		paySource = thePaySource;
		saveConfiguration();
	}
	
	private FilterState filterState;
	public FilterState getFilterState(){
		return filterState;
	}
	public void setFilterState(FilterState theFilterState){
		filterState = theFilterState;
		saveConfiguration();
	}
	
	private Set<Material> filterMaterials;
	public Set<Material> getFilterMaterials(){
		return filterMaterials;
	}

	public void addFilterMaterial(Material theMaterial) {
		getFilterMaterials().add(theMaterial);
		saveConfiguration();
	}

	public void removeFilterMaterial(Material theMaterial) {
		getFilterMaterials().remove(theMaterial);
		saveConfiguration();
	}
}
